#include "kp.h"

extern "C" {
	#define __STRICT_ANSI__
	#include <json/json.h>
}

#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <unistd.h>

using namespace std;


int KPOnlineStorage::connect()
{
	kpfs_conf conf;
	memset(&conf,0,sizeof(kpfs_conf));
	strncpy(conf.consumer_key,Config::Get("kpfs.consumer_key").c_str(),64);
	strncpy(conf.consumer_secret,Config::Get("kpfs.consumer_secret").c_str(),64);
	strncpy(conf.root,Config::Get("kpfs.root").c_str(),64);
	strncpy(conf.oauth_json_file,Config::Get("kpfs.oauth_json_file").c_str(),KPFS_MAX_PATH);
	strncpy(conf.writable_tmp_path,Config::Get("kpfs.writable_tmp_path").c_str(),KPFS_MAX_PATH);
	kpfs_conf_load(conf);
	kpfs_oauth_init();
	while(kpfs_oauth_load() != KPFS_RET_OK)
	{
		int ret;
		printf("This is the first time you use kpfs.\n");
		ret = kpfs_oauth_request_token();
		if (KPFS_RET_OK != ret) {
			return -1;
		}
		ret = kpfs_oauth_authorize();
		if (KPFS_RET_OK != ret) {
			return -1;
		}
		ret = kpfs_oauth_access_token();
		if (KPFS_RET_OK != ret) {
			KPFS_LOG("Fail to get oauth token for kpfs.\n");
			return -1;
		}
	}
}

void KPOnlineStorage::disconnect()
{
}


int KPOnlineStorage::get(const char* pathname,char* buffer,size_t size)
{
	char *url = NULL;
	url = kpfs_api_download_link_create(pathname);
	return kpfs_curl_range_get(url, buffer, 0, size) < 0;
}
int KPOnlineStorage::put(const char* pathname,const char* buffer,size_t size)
{
	FILE* fp = fopen("tmp","wb");
	fwrite(buffer,1,size,fp);
	fclose(fp);
	if (kpfs_api_upload_file((char *)pathname, "tmp")  == NULL)
		return -1;
	unlink("tmp");
	return 0;
}
int KPOnlineStorage::del(const char* pathname)
{
	return kpfs_api_delete((char*)pathname);
}
int KPOnlineStorage::mkdir(const char* path,const char* name)
{
	char *tmp = malloc(strlen(path)+strlen(name) + 2);
	sprintf(tmp,"%s/%s",path,name);
	if (KPFS_RET_FAIL == kpfs_api_create_folder(tmp))
	{
		free(tmp);
		return -1;
	}
	free(tmp);
	return 0;
}
int KPOnlineStorage::rmdir(const char* path,const char* name)
{
	char *tmp = malloc(strlen(path)+strlen(name) + 2);
	sprintf(tmp,"%s/%s",path,name);
	if (KPFS_RET_FAIL == kpfs_api_delete(tmp))
	{
		free(tmp);
		return -1;
	}
	free(tmp);
	return 0;
}
struct NetFile* KPOnlineStorage::lsdir(const char* path,OUT int* size /* numbner of struct NetFile */)
{
	char *response = NULL;
	json_object *jobj;
	json_object *tmp_jobj;
	int len = 0;
	int jj = 0;
	kpfs_ret ret = KPFS_RET_FAIL;
	struct NetFile* files;

	response = (char *)kpfs_api_metadata((char*)path);
	KPFS_LOG("response %s:\n", response);

	jobj = json_tokener_parse(response);
	if (NULL == jobj || is_error(jobj)) 
	{
		KPFS_FILE_LOG("%s:%d, json_tokener_parse return error.\n", __FUNCTION__, __LINE__);
		KPFS_SAFE_FREE(response);
		return NULL;
	}

	json_object_object_foreach(jobj, key, val) 
	{
		if (!strcmp(key, KPFS_ID_MSG)) 
		{
			if (json_type_string == json_object_get_type(val)) 
			{
				if (0 == strcmp(KPFS_MSG_STR_REUSED_NONCE, json_object_get_string(val))) 
				{
					KPFS_FILE_LOG("%s:%d, receive reused nonce.\n", __FUNCTION__, __LINE__);
					goto error_out;
				}
			}
		}
		else if (!strcmp(key, KPFS_ID_PATH)) 
		{
		}
		else if (!strcmp(key, KPFS_ID_ROOT)) 
		{
			if (json_type_string == json_object_get_type(val)) 
			{
			}
		}
		else if (!strcmp(key, KPFS_ID_HASH)) 
		{
		}
		else if (!strcmp(key, KPFS_ID_FILES)) 
		{
			if (json_type_array == json_object_get_type(val)) 
			{
				int j = 0, array_len = 0;

				array_len = json_object_array_length(val);

				files = new struct NetFile[array_len];

				 int isdeleted = 0;

				for (j = 0; j < array_len; j++) 
				{
					tmp_jobj = json_object_array_get_idx(val, j);
					if (tmp_jobj && !is_error(tmp_jobj)) 
					{
						isdeleted = 0;
						json_object_object_foreach(tmp_jobj, key2, val2) 
						{
							if (!strcmp(key2, KPFS_ID_IS_DELETED)) {
								if (json_type_boolean == json_object_get_type(val2)) {
									isdeleted = json_object_get_boolean(val2) == TRUE ? 1 : 0;
								}
							} else if (!strcmp(key2, KPFS_ID_NAME)) {
								if (json_type_string == json_object_get_type(val2)) {
									strcpy(files[jj].fileName,json_object_get_string(val2));
									//KPFS_FILE_LOG("%s:%d, name: %s.\n", __FUNCTION__, __LINE__, node->name);
								}
							} else if (!strcmp(key2, KPFS_ID_REV)) {
								if (json_type_string == json_object_get_type(val2)) {
/*									node->revision = strdup(json_object_get_string(val2));
									KPFS_FILE_LOG("%s:%d, revision: %s.\n", __FUNCTION__, __LINE__,
										      json_object_get_string(val2));*/
								}
							} else if (!strcmp(key2, KPFS_ID_CREATE_TIME)) {
								/*if (json_type_string == json_object_get_type(val2)) {
									char str[128] = { 0 };
									snprintf(str, sizeof(str), "%s", json_object_get_string(val2));
									node->st.st_ctime = kpfs_node_str2time(str);
									KPFS_FILE_LOG("%s:%d, ctime: %d.\n", __FUNCTION__, __LINE__, node->st.st_ctime);
								}*/
							} else if (!strcmp(key2, KPFS_ID_MODIFY_TIME)) {
								/*if (json_type_string == json_object_get_type(val2)) {
									char str[128] = { 0 };
									snprintf(str, sizeof(str), "%s", json_object_get_string(val2));
									node->st.st_mtime = kpfs_node_str2time(str);
									KPFS_FILE_LOG("%s:%d, mtime: %d.\n", __FUNCTION__, __LINE__, node->st.st_mtime);
								}*/
							} else if (!strcmp(key2, KPFS_ID_SIZE)) {
								if (json_type_int == json_object_get_type(val2)) {
									files[jj].size = json_object_get_int(val2);
									//KPFS_FILE_LOG("%s:%d, size: %d.\n", __FUNCTION__, __LINE__, node->st.st_size);
								}
							} else if (!strcmp(key2, KPFS_ID_TYPE)) {
								if (json_type_string == json_object_get_type(val2)) {
									if (0 == strcasecmp(KPFS_NODE_TYPE_STR_FILE, json_object_get_string(val2))) {
										files[jj].folder = 0;
									} else {
										files[jj].folder = 1;
									}
								}
							} 
							else if (!strcmp(key2, KPFS_ID_FILE_ID)) {
								/*if (json_type_string == json_object_get_type(val2)) {
									node->id = strdup(json_object_get_string(val2));
									KPFS_FILE_LOG("%s:%d, id: %s.\n", __FUNCTION__, __LINE__, node->id);
								}*/
							}
						}
						if (isdeleted == 0) jj++;
					}
				}
			}
		}
	}
	*size = jj;
	return files;
error_out:
	json_object_put(jobj);

	KPFS_SAFE_FREE(response);
	return NULL;
}
int KPOnlineStorage::move(const char* oldPath,const char* newPath)
{
	return kpfs_api_move((char*)oldPath, (char*)newPath);
}
int KPOnlineStorage::freespace()
{
	//off_t quota_total = kpfs_util_account_quota_total_get();
	//off_t quota_used = kpfs_util_account_quota_used_get();
	return -1;//quota_total - quota_used;
}
